#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/highgui.hpp>
using namespace std;
using namespace cv;

vector<Vec4i> hierarchy;
int main(int argv, char **argc)
{

    Ptr<BackgroundSubtractor> pBackSub;

    pBackSub = createBackgroundSubtractorMOG2();
    VideoCapture capture("./water.avi");
    if (!capture.isOpened())
    {
        //error in opening the video input
        printf("could not load image..\n");
        return false;
    }
    Mat frame, hsv, fgMask, mask;
    while (true)
    {
        capture >> frame;
        // frame = imutils.resize(frame, 600)

        if (frame.empty())
            break;

        cvtColor(frame, hsv, COLOR_BGR2HSV);
        inRange(hsv, Scalar(0, 43, 46), Scalar(26, 255, 255), mask);
        GaussianBlur(frame, frame, Size(11, 11), 3, 3);
        erode(mask, mask, Mat(), Point(-1, -1), 2);
        dilate(mask, mask, Mat(), Point(-1, -1), 4);
        ;
        // morphologyEx(mask, mask, MORPH_OPEN, kernel, Point(-1, -1));
        // vector<Point2f> cnt=cnts[0];
        pBackSub->apply(mask, fgMask);

//   vector<vector<Point> >corners;
//     //【5】查找轮廓
//     findContours(fgMask, corners, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
        // Mat kernel = getStructuringElement(MORPH_RECT, Size(15, 15), Point(-1, -1));
        // vector<Point2f> corners; //提供初始角点的坐标位置和精确的坐标的位置
        // int maxcorners = 200;
        // double qualityLevel = 0.01; //角点检测可接受的最小特征值
        // double minDistance = 10;    //角点之间最小距离
        // int blockSize = 3;          //计算导数自相关矩阵时指定的领域范围
        // double k = 0.04;            //权重系数
        // goodFeaturesToTrack(fgMask, corners, maxcorners, qualityLevel, minDistance, Mat(), blockSize, false, k);
Mat canny_output;
int thresh = 500;
RNG rng(12345);
    Canny( fgMask, canny_output, thresh, thresh*2 );
    vector<vector<Point> > contours;
    findContours( canny_output, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0) );
    vector<RotatedRect> minRect( contours.size() );
    // vector<RotatedRect> minEllipse( contours.size() );
    for( size_t i = 0; i < contours.size(); i++ )
    {
        minRect[i] = minAreaRect( contours[i] );

    }
    Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
    for( size_t i = 0; i< contours.size(); i++ )
    {
        Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
        // contour
        drawContours( drawing, contours, (int)i, color );
        // ellipse
        // ellipse( drawing, minEllipse[i], color, 2 );
        // rotated rectangle
        Point2f rect_points[4];
        minRect[i].points( rect_points );
        for ( int j = 0; j < 4; j++ )
        {
            line( drawing, rect_points[j], rect_points[(j+1)%4], color );
        }
    }
       
        // RotatedRect rRect = RotatedRect(Point2f(100,100), Size2f(100,50), 30);
        // Point2f vertices[4];
        // rRect.points(vertices);
        // for (int i = 0; i < 4; i++)
        //     line(test_image, vertices[i], vertices[(i+1)%4], Scalar(0,255,0), 2);
        // Rect brect = rRect.boundingRect();
        // rectangle(test_image, brect, Scalar(255,0,0), 2);
        // imshow("rectangles", test_image);
        // waitKey(0);
        // if (corners.size() != 0)
        // {
        // vector<RotatedRect> rect;
        // for (int i = 0; i < corners.size(); i++)
        // {
        //     rect.push_back(minAreaRect(corners[i]));
        //     Point2f vertices[4]; //定义矩形的4个顶点
        //     rect[i].points(vertices); //计算矩形的4个顶点
        //     // cout << "1" << rect[i] << endl;
        //     for (int i = 0; i < 4; i++)
        //         line(fgMask, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0), 1);
        // }
        // }
        imshow("xx", drawing);
        //提取视频row and column
        // int wid = frame.rows;
        // int hei = frame.cols;
        // //提取corner points
        // int uplx = 0;
        // int uply = 0;
        // int downlx = 0;
        // int downly = 0;
        // int uprx = 0;
        // int upry = 0;
        // int downrx = 0;
        // int downry = 0;
        // //遍历点集
        // if (corners.size() != 0)
        // {
        //     int xt = 0, yt = 0;
        //     int wi = 0, he = 0;
        //     //冒泡算法
        //     int xx = 0;
        //     int yy = 0;
        //     int len = corners.size();
        //     for (int i = 0; i < len - 1; ++i)
        //         for (int j = 0; j < len - 1 - i; ++j)
        //             if (corners[j].x > corners[j + 1].x)
        //             {
        //                 xx = corners[j].x;
        //                 yy = corners[j].y;
        //                 xt += corners[i].x;
        //                 yt += corners[i].y;
        //                 corners[j].x = corners[j + 1].x;
        //                 corners[j].y = corners[j + 1].y;
        //                 corners[j + 1].x = xx;
        //                 corners[j + 1].y = yy;

        //             }
        //     wi = xt / corners.size();
        //     he = yt / corners.size();
        //     int bool1=1;
        //     for (int i = 0; i < corners.size(); i++)
        //     {
        //         if (bool1=1&corners[i].x<wi&corners[i].y<he)
        //         {
        //             uplx = corners[i].x;
        //             uply=corners[i].y;
        //             bool1=0;
        //         }
        //     }

        // }
        // cout << "左上坐标：" << uplx << "," << uply << endl;
        // cout << "左上坐标：" << uplx << "," << uply << endl;
        // cout << "右上坐标：" << uprx<< "," << upry << endl;
        // cout << "右下坐标：" << downrx << "," << downry << endl;
        // cout << "左下坐标：" << downlx << "," << downly << endl;

        // //绘制角点
        // RNG rng(12345); //控制随机生成数,彩色点标记
        // for (unsigned i = 0; i < corners.size(); i++)
        // {

        //     circle(frame, corners[i], 2, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), -1, 8, 0);
        //     // cout << "角点坐标：" <<i<< corners[i] << endl;
        // }

        // imshow("Frame", frame);
        // imshow("FG Mask", fgMask);

        //get the input from the keyboard
        int keyboard = waitKey(10);
        if (keyboard == 'q' || keyboard == 27)
            break;
    }
    capture.release();
    return (0);
}
